package cn.exrick.controller;

import cn.exrick.pojo.TbMember;
import cn.exrick.pojo.TbMemberVipRule;
import cn.exrick.pojo.TbOrder;
import cn.exrick.service.MemberFrontService;
import cn.exrick.service.MemberService;
import cn.exrick.service.MemberVipRuleService;
import cn.exrick.service.OrderService;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayConstants;
import com.alipay.api.internal.util.AlipaySignature;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLDecoder;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Controller
public class NotifyController {

    private Logger log = LoggerFactory.getLogger(NotifyController.class);

    @Value("${ALIPAY_APP_ID}")
    private String ALIPAY_APP_ID;
    @Value("${ALIPAY_SELLER_ID}")
    private String ALIPAY_SELLER_ID;
    @Value("${ALIPAY_PUBLIC_KEY}")
    private String ALIPAY_PUBLIC_KEY;

    @Autowired
    private OrderService orderService;
    @Autowired
    private MemberService memberService;
    @Autowired
    private MemberFrontService memberFrontService;
    @Autowired
    private MemberVipRuleService memberVipRuleService;

    /**
     * 支付宝支付回调
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping(value = "/notify/alipay/pay", method = {RequestMethod.POST, RequestMethod.GET })
    public void aliAppPayNotify(HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        log.info("支付宝支付回调======================>");
        Map<String, String> paramsMap = getParamMap(request);

        log.info("支付宝支付回调参数：{}", JSONObject.toJSONString(paramsMap));
        boolean verify = AlipaySignature.rsaCheckV1(paramsMap, ALIPAY_PUBLIC_KEY, AlipayConstants.CHARSET_UTF8, AlipayConstants.SIGN_TYPE_RSA2);
        if(verify){
            log.info("支付宝支付回调验签成功!");
            String tradeStatus = request.getParameter("trade_status");
            if("TRADE_FINISHED".equals(tradeStatus)){  // 交易完成
                log.info("支付宝支付交易完成!");
            }else if("TRADE_SUCCESS".equals(tradeStatus)){  // 支付成功
                log.info("支付宝支付付款成功!");
                String appId = request.getParameter("app_id");
                if(!ALIPAY_APP_ID.equals(appId)){
                    log.info("支付宝支付回调,APP_ID错误,系统APP_ID[{}],回调APP_ID[{}]", ALIPAY_APP_ID, appId);
                    response.getWriter().print("failure");
                    return;
                }

                String passbackParams = request.getParameter("passback_params");
                passbackParams = URLDecoder.decode(passbackParams, "utf-8");
                log.info("支付宝支付回调,passbackParams={}", passbackParams);

                Map<String, Object> passbackMap = getUrlParams(passbackParams);
                log.info("支付宝支付回调,passbackParamsMap={}", JSONObject.toJSONString(passbackMap));

                String type = String.valueOf(passbackMap.get("type"));
                if(StringUtils.isNotBlank(type) && "order".equals(type)){
                    String orderId = request.getParameter("out_trade_no");
                    TbOrder order = orderService.getById(orderId);
                    if(null == order){
                        log.info("支付宝支付回调,订单[{}]不存在", orderId);
                        response.getWriter().print("failure");
                        return;
                    }
                    if(0 != order.getStatus()){
                        log.info("支付宝支付回调,订单状态[{}]错误", order.getStatus());
                        response.getWriter().print("failure");
                        return;
                    }

                    // 更新订单
                    order.setStatus(1); // 已付款
                    order.setPaymentType(1);
                    order.setPaymentTime(new Date());
                    order.setUpdateTime(new Date());

                    orderService.update(order);

                    // todo 保存支付信息

                    response.getWriter().print("success");
                    return;
                }

                if(StringUtils.isNotBlank(type) && "memberVip".equals(type)){
                    String ruleId = String.valueOf(passbackMap.get("memberVipRuleId"));
                    String memberId = String.valueOf(passbackMap.get("memberId"));

                    TbMember tbMember = memberService.getMemberById(Long.parseLong(memberId));
                    TbMemberVipRule tbMemberVipRule = memberVipRuleService.queryById(Integer.parseInt(ruleId));

                    int month = tbMemberVipRule.getMonth();
                    Calendar calendar = Calendar.getInstance();
                    if(tbMember.getVip() == 1){
                        calendar.setTime(tbMember.getExpireTime());
                    }else{
                        calendar.setTime(new Date());
                    }
                    calendar.add(Calendar.MONTH, month);
                    calendar.set(Calendar.HOUR_OF_DAY, 0);
                    calendar.set(Calendar.MINUTE, 0);
                    calendar.set(Calendar.SECOND, 0);
                    calendar.set(Calendar.MILLISECOND, 0);

                    memberFrontService.updateMemVip(tbMember.getId(), 1, calendar.getTime());

                    response.getWriter().print("success");
                    return;
                }

                if(StringUtils.isNotBlank(type) && "memberCertify".equals(type)){
                    String memberId = String.valueOf(passbackMap.get("memberId"));

                    TbMember tbMember = memberService.getMemberById(Long.parseLong(memberId));

                    if(tbMember.getCertify() == 0){
                        // 0未认证 1已认证 2已支付，未认证
                        memberFrontService.updateMemCertify(tbMember.getId(), 2);
                    }

                    response.getWriter().print("success");
                    return;
                }

            }else if("TRADE_CLOSED".equals(tradeStatus)){   // 关闭交易
                log.info("支付宝支付交易关闭!");
            }else{
                log.info("支付宝支付交易类型错误!交易类型[{}]", tradeStatus);
            }

        }else{
            log.info("支付宝支付回调验签错误!");
            response.getWriter().print("failure");
        }
    }

    private Map<String, String> getParamMap(HttpServletRequest request){
        Map<String, String> paramsMap = new HashMap<>();
        Map requestParamsMap = request.getParameterMap();
        for (Iterator it = requestParamsMap.keySet().iterator(); it.hasNext();){
            String paramName = String.valueOf(it.next());
            String[] paramValues = (String[]) requestParamsMap.get(paramName);
            String paramValue = "";
            for (int i = 0; i < paramValues.length; i++){
                paramValue = paramValue + paramValues[i];
                if(i != paramValues.length - 1){
                    paramValue = paramValue + ",";
                }
            }
            paramsMap.put(paramName, paramValue);
        }
        return paramsMap;
    }

    public Map<String, Object> getUrlParams(String param) {
        Map<String, Object> map = new HashMap<String, Object>(0);
        if (StringUtils.isBlank(param)) {
            return map;
        }
        String[] params = param.split("&");
        for (int i = 0; i < params.length; i++) {
            String[] p = params[i].split("=");
            if (p.length == 2) {
                map.put(p[0], p[1]);
            }
        }
        return map;
    }

}
